<?php

/**
 * Базовая реализация контроллера фронтенда для модуля.
 *
 */
class Kernel_Controller_Frontend extends Kernel_Controller_Module 
{

    /**
     * Наименование действия по умолчанию.
     *
     * @var string
     */
    public $default;

    /**
     * Указывает, нужно ли перенаправлять агента на URL, соответствующий действию
     * по умолчанию, через внешнее перенаправление.
     *
     * @var boolean
     */
    public $redirect = false;

    /**
     * Позиция секции URI, в которой находится наименование действия.
     *
     * @var integer
     */
    protected $_action_pos = 1;

    /**
     * Возвращает описание компонента, который обработает действие, полученное
     * из запроса.
     *
     * @return  Kernel_Token
     */
    protected function _getFilterToken() 
    {
        // get action name from URL
        if (is_null($action = $this->_getAction())) {
            if ($this->redirect) {
                // relocate agent to the default action
                $this->_redirect();
            } else {
                // assign default action name
                $action = $this->default;
            }
        } elseif ($action == $this->default && !$this->redirect) {
            // предотвращаем дублирование URL'ов с явно и неявно указанным
            // действием по умолчанию
            $this->_abort('Default action is specified explicitly');
        }
        
        $option = (int)Application::dummy()->html()->getOption();
        return new Kernel_Token($action, 
            $option > 0 ? array('option' => $option) : array());
    }

    /**
     * Возвращает наименование действия, полученное из URL.
     *
     * @return  string
     */
    protected function _getAction() 
    {
        return Application::getRequest()->uri($this->_action_pos);
    }

    /**
     * Возвращает наименование класса компонента, который обработает запрошенное
     * действие.
     *
     * @param   string  $name
     * @return  string
     */
    protected function _getFilterClassName($name) 
    {
        return str_camelize($this->module) . '_Action_' . str_camelize($name);
    }

    /**
     * Создает объект фильтра. Затеваем эту хитрую проверку для того, чтобы
     * абстрактные классы действий можно было безопасно класть рядом с
     * конкретными, которые их наследуют.
     *
     * @param   string  $class
     * @param   array   $params
     * @return  Kernel_Filter_Interface
     */
    protected function _create($class, $params) 
    {
        $reflection = new ReflectionClass($class);
        if (!$reflection->isInstantiable()) {
            $this->_abort('Specified class is not instantiable');
        }
        return parent::_create($class, $params);
    }

    /**
     * Redirect agent to the default action. 
     *
     */
    private function _redirect() 
    {
        $this->_location(
            (Application::getRequest()->isMultilang() ? __lang() . '/' : '') . 
            Application::getRequest()->uri(0) . '/' . $this->default . '/', true
        );
    }
    
}
